﻿using Microsoft.Extensions.Hosting;
using Quartz.Spi;
using Quartz;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
using System;

namespace shop.Web.PlanTask
{

    /// <summary> 自定义的  Quartz 服务 可以避免回收资源后无法运行任务 </summary>
    public class QuartzHostedService : BackgroundService
    {
        private readonly ISchedulerFactory _schedulerFactory;
        private readonly IJobFactory _jobFactory;
        private readonly IEnumerable<JobSchedule> _jobSchedules;
        private IScheduler _scheduler;

        public QuartzHostedService(
            ISchedulerFactory schedulerFactory,
            IJobFactory jobFactory,
            IEnumerable<JobSchedule> jobSchedules)
        {
            _schedulerFactory = schedulerFactory;
            _jobFactory = jobFactory;
            _jobSchedules = jobSchedules;
        }

        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            //throw new NotImplementedException();
            NLog.LogManager.GetCurrentClassLogger().Warn("启动QuartzHostedService");


            _scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
            _scheduler.JobFactory = _jobFactory;

            foreach (var jobSchedule in _jobSchedules)
            {
                var job = CreateJob(jobSchedule);
                var trigger = CreateTrigger(jobSchedule);

                await _scheduler.ScheduleJob(job, trigger, cancellationToken);
            }


            await _scheduler.Start(cancellationToken);
        }

        //public async Task StartAsync(CancellationToken cancellationToken)
        //{
        //    NLog.LogManager.GetCurrentClassLogger().Warn("启动QuartzHostedService");


        //    _scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
        //    _scheduler.JobFactory = _jobFactory;

        //    foreach (var jobSchedule in _jobSchedules)
        //    {
        //        var job = CreateJob(jobSchedule);
        //        var trigger = CreateTrigger(jobSchedule);

        //        await _scheduler.ScheduleJob(job, trigger, cancellationToken);
        //    }



        //    await _scheduler.Start(cancellationToken);
        //}

        //public override async Task StopAsync(CancellationToken cancellationToken)
        //{
        //    if (_scheduler != null)
        //    {
        //        await _scheduler.Shutdown(cancellationToken);
        //    }
        //}

        private IJobDetail CreateJob(JobSchedule schedule)
        {
            var jobType = schedule.JobType;
            return JobBuilder
                .Create(jobType)
                .WithIdentity(jobType.FullName)
                .WithDescription(jobType.Name)
                .Build();
        }

        private ITrigger CreateTrigger(JobSchedule schedule)
        {
            return TriggerBuilder
                .Create()
                .WithIdentity($"{schedule.JobType.FullName}.trigger")
                .WithCronSchedule(schedule.CronExpression)
                .WithDescription(schedule.CronExpression)
                .Build();
        }




        //private void RegisterJobs()
        //{


        //}


    }

    public class JobSchedule
    {
        public JobSchedule(Type jobType, string cronExpression)
        {
            JobType = jobType;
            CronExpression = cronExpression;
        }

        public Type JobType { get; }
        public string CronExpression { get; }
    }

}
